﻿using Domain.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.ComponentModel;
using System.Data.Common;
using System.Reflection;

namespace Domain
{
    public static partial class ServiceExtensions
    {
        /// <summary>
        /// 配置数据库上下文
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration">配置</param>
        /// <param name="databaseType">数据库类型</param>
        /// <param name="connectionName">连接名称</param>
        /// <returns></returns>
        public static IServiceCollection AddDbContext(
            this IServiceCollection services,
            IConfiguration configuration,
            DataBaseType databaseType,
            string connectionName)
        {
            switch (databaseType)
            {
                case DataBaseType.SqlServer:
                    return services.ConfigSqlServerDBContext(configuration, connectionName);
                case DataBaseType.MySql:
                    return services.ConfigMySqlDBContext(configuration, connectionName);
            }
            throw new Exception("请选择正确的数据库");
        }

        /// <summary>
        /// 配置数据库
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        /// <param name="connectionName">数据库连接字符串的名字,默认为Default</param>
        /// <returns></returns>
        public static IServiceCollection ConfigSqlServerDBContext(this IServiceCollection services, IConfiguration configuration, string connectionName)
        {
            var connection = configuration.GetConnectionString(connectionName);
            if (string.IsNullOrEmpty(connection))
            {
                throw new ArgumentNullException($"Please provide the DB connection with the {nameof(connectionName)}  name");
            }
            var loggerFactory = services.BuildServiceProvider().GetRequiredService<ILoggerFactory>();
            services.AddDbContext<RepositoryContext>(options =>
            {
                options
                //.UseLazyLoadingProxies()
                .ConfigureWarnings(action =>
                {
                    //action.Ignore(CoreEventId.DetachedLazyLoadingWarning);
                })
                .UseSqlServer(connection, optionsAction =>
                {
                    optionsAction.CommandTimeout(60);
                    //配置迁移记录表
                    var assembly = Assembly.GetAssembly(typeof(RepositoryContext)).GetName().Name;
                    optionsAction.MigrationsAssembly(assembly);
                    optionsAction.MigrationsHistoryTable("MigrationHistory", "dbo");
                })
                .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
                .UseLoggerFactory(loggerFactory);
            }, ServiceLifetime.Transient);
            return services;
        }

        public static IServiceCollection ConfigMySqlDBContext(this IServiceCollection services, IConfiguration configuration, string connectionName)
        {
            var connection = configuration.GetConnectionString(connectionName);
            if (string.IsNullOrEmpty(connection))
            {
                throw new ArgumentNullException($"Please provide the DB connection with the {nameof(connectionName)}  name");
            }
            var loggerFactory = services.BuildServiceProvider().GetRequiredService<ILoggerFactory>();
            services.AddDbContext<RepositoryContext>(options =>
            {
                options
                //.UseLazyLoadingProxies()
                .ConfigureWarnings(action =>
                {
                    //action.Ignore(CoreEventId.DetachedLazyLoadingWarning);
                })
                .UseMySql(connection, optionsAction =>
                {
                    optionsAction.CommandTimeout(60);
                    //配置迁移记录表
                    var assembly = Assembly.GetAssembly(typeof(RepositoryContext)).GetName().Name;
                    optionsAction.MigrationsAssembly(assembly);
                    optionsAction.MigrationsHistoryTable("MigrationHistory");
                })
                .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
                .UseLoggerFactory(loggerFactory);
            }, ServiceLifetime.Transient);
            return services;
        }

    }
    [Description("数据库类型")]
    public enum DataBaseType
    {
        SqlServer =0,
        MySql = 1,
    }
}
